#include "EngineServer.hpp"
#include <csignal> 

// 服务器指针
static EngineServer * serverPtr = nullptr;


// 自定义信号处理：优雅退出
void signalHandler(int signum){
    cout << "--------------------------------------------" << endl;
    cout << endl << "Interrupt signal (" << signum << ") received.\n";

    serverPtr->stop(); // 停止事件循环, 结束线程池
}


// 任务类型
// 自定义线程池子线程对于客户消息的处理方式
class MyTask {
public: 
    static void process(const string & msg, const TcpConnectionPtr & con, EngineServer* server){
        if (server == nullptr) {
            std::cerr << "serverPtr is nullptr! Task process failed." << endl;
            return;
        }
        
        istringstream iss(msg);
        string type, content;
        string result;
        iss >> type >> content;
        if (type == "keywords") {
            bool hit = server->_keywordCache.get(content, result);
            if (!hit) {
                #if DEBUG
                cout << "keywords hit cache failed" << endl;
                #endif
                Json keywordsJson = server->getCandidateWords(content);
                result = keywordsJson.dump(2);
                server->_keywordCache.put(content, result);
            } 
            con->sendInLoop(result);

        } else if (type == "pages") {
            bool hit = server->_pageCache.get(content, result);
            if (!hit) {
                #if DEBUG
                cout << "pages hit cache failed" << endl;
                #endif
                shared_ptr<Json> pagesJson = server->getCandidatePages(content);
                result = pagesJson->dump(2);
                server->_pageCache.put(content, result);
                
            } 
            con->sendInLoop(result);
            
        } else {
            con->sendInLoop("invalid request type");
        }
    }
};


// 回调函数: 打印新建连接的信息
void onNewConnection(const TcpConnectionPtr & conn){
    cout << "new connection: " << conn->toString() << endl;
}

// 回调函数：处理客户端消息
void onMessage(const TcpConnectionPtr & conn){ 
    string message = conn->recv(); // 接收客户消息
    cout << "client[" << conn->peerToString() << "] message: " 
         << message << endl;  // 打印客户消息

    // 将客户消息以及对消息的处理方式、连同对应TCP连接一起打包
    serverPtr->addTask(std::bind(&MyTask::process, message, conn, serverPtr));  // 传递任务给子线程
}

// 回调函数：打印退出客户端的信息
void onClose(const TcpConnectionPtr & conn){
    cout << "client[" << conn->peerToString() << "] closed connection" << endl;
}


int main() {
    // 注册2号信号：按下 Ctrl+C 优雅退出
    signal(SIGINT, signalHandler); 

    // 创建搜索引擎服务器
    EngineServer server("192.168.43.128", 20001, 4, 10, 1000, 16, 2);

    // 初始化全局服务器指针
    serverPtr = &server;

    // 设置回调事件
    server.setAllCallback(onNewConnection, onMessage, onClose);

    // 设置必要的文件
    server.setKeyWordsRecommender("./corpus_processed/cnDictionary.txt", "./corpus_processed/cnIndex.txt");
    server.setPageRecommender("./corpus_processed/inverted_index.txt", 
                              "./corpus_processed/pageOffsetLib.txt", 
                              "./corpus_processed/pageLib.txt", 
                              "./corpus_processed/cn_stopwords.txt");

    // 启动服务器
    server.start();

    // 收到信号后，有序退出程序
    cout << "Process terminates successfully." << endl;

    return 0;
}